﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using TextGlow.Control.Utilities;

namespace TextGlow.Control.Model
{
  public class Style
  {
    private readonly DelegateKeyedCollection<ConditionalTableStyleType, ConditionalTableStyle> _conditionalTableStyles =
      new DelegateKeyedCollection<ConditionalTableStyleType, ConditionalTableStyle>(s => s.Type);

    private string _basedOnStyleId;
    private string _linkedStyleId;
    private string _nextParagraphStyleId;
    private string _id;
    private string _type;
    private string _name;
    //qFormat
    private bool? _primaryStyle;
    private bool? _default;
    private ParagraphProperties _paragraphProperties;
    private RunProperties _runProperties;
    private TableProperties _tableProperties;
    private TableCellProperties _tableCellProperties;

    private Content _parentContent;

    public DelegateKeyedCollection<ConditionalTableStyleType, ConditionalTableStyle> ConditionalTableStyles
    {
      get { return _conditionalTableStyles; }
    }

    public Content ParentContent
    {
      get { return _parentContent; }
      set { _parentContent = value; }
    }

    public RunProperties RunProperties
    {
      get { return _runProperties; }
      set { _runProperties = value; }
    }

    public ParagraphProperties ParagraphProperties
    {
      get { return _paragraphProperties; }
      set { _paragraphProperties = value; }
    }

    public TableProperties TableProperties
    {
      get { return _tableProperties; }
      set { _tableProperties = value; }
    }

    public TableCellProperties TableCellProperties
    {
      get { return _tableCellProperties; }
      set { _tableCellProperties = value; }
    }

    public bool? Default
    {
      get { return _default; }
      set { _default = value; }
    }

    public bool? PrimaryStyle
    {
      get { return _primaryStyle; }
      set { _primaryStyle = value; }
    }

    public string Name
    {
      get { return _name; }
      set { _name = value; }
    }

    public string Id
    {
      get { return _id; }
      set { _id = value; }
    }

    public string Type
    {
      get { return _type; }
      set { _type = value; }
    }

    public string BasedOnStyleId
    {
      get { return _basedOnStyleId; }
      set { _basedOnStyleId = value; }
    }

    public Style BasedOnStyle
    {
      get { return DocumentContent.GetStyle(_parentContent, _basedOnStyleId); }
    }

    public string LinkedStyleId
    {
      get { return _linkedStyleId; }
      set { _linkedStyleId = value; }
    }

    public Style LinkedStyle
    {
      get { return DocumentContent.GetStyle(_parentContent, _linkedStyleId); }
    }

    public string NextParagraphStyleId
    {
      get { return _nextParagraphStyleId; }
      set { _nextParagraphStyleId = value; }
    }

    public Style NextParagraphStyle
    {
      get { return DocumentContent.GetStyle(_parentContent, _nextParagraphStyleId); }
    }

    public Style(Content parentContent, XElement element)
    {
      if (element == null)
        throw new ArgumentNullException("element");

      _parentContent = parentContent;

      XNamespace ns = element.Name.Namespace;

      _id = (string)element.Attribute(ns + "styleId");
      _type = (string)element.Attribute(ns + "type");
      _default = XmlUtils.OnOffToBoolean((string)element.Attribute(ns + "default"));
      _basedOnStyleId = XmlUtils.GetValue(element.Element(ns + "basedOn"));
      _name = XmlUtils.GetValue(element.Element(ns + "name"));
      _linkedStyleId = XmlUtils.GetValue(element.Element(ns + "link"));
      _primaryStyle = XmlUtils.GetBoolean(element.Element(ns + "qFormat"));

      _paragraphProperties = new ParagraphProperties(this, element.Element(ns + "pPr"));
      _runProperties = new RunProperties(this, element.Element(ns + "rPr"));
      _tableProperties = new TableProperties(this, element.Element(ns + "tblPr"));
      _tableCellProperties = new TableCellProperties(this, element.Element(ns + "tcPr"));

      var conditionalTableStyles = from e in element.Elements(ns + "tblStylePr")
                                   select new ConditionalTableStyle(this, e);

      _conditionalTableStyles.AddRange(conditionalTableStyles);
    }
  }
}